package com.ipan.builder.db;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.cfg.JDBCMetaDataConfiguration;
import org.hibernate.cfg.reveng.OverrideRepository;
import org.hibernate.cfg.reveng.TableFilter;
import org.hibernate.mapping.Table;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;

import com.ipan.builder.entity.EntityOpUtils;
import com.ipan.builder.entity.JpaEntityCfg;

/**
 * 数据库操作具体实现
 * 
 * @author iPan
 * @version 2013-11-27
 */
public class DefaultDataBaseOp extends AbstractDataBaseOp {

	private boolean script = true;

	public boolean isScript() {
		return script;
	}

	public void setScript(boolean script) {
		this.script = script;
	}

	public void updateAllTables() {
		doUpdateTables(EntityOpUtils.loadJpaEntityCfgList());
	}

	public void updateTable(List<JpaEntityCfg> jpaEntityCfgList) {
		doUpdateTables(jpaEntityCfgList);
	}
	
	public void updateTable(JpaEntityCfg jpaEntityCfg) {
		if (jpaEntityCfg != null) {
			List<JpaEntityCfg> list = new ArrayList<JpaEntityCfg>();
			list.add(jpaEntityCfg);
			doUpdateTables(list);
		}
	}

	public void createAllEntities() {
		configuration.readFromJDBC(getCatalogName(), getSchemaName());
		doExportPojo();
	}

	public void createEntity(String[] tables) {
		if (tables == null || tables.length < 1) {
			return;
		}
		OverrideRepository or = new OverrideRepository();
		preReverseTable(tables, or);
		configuration.readFromJDBC(getCatalogName(), getSchemaName());
		doExportPojo();
	}

	public void createEntityByFilter(String[] matchTables) {
		if (matchTables == null || matchTables.length < 1) {
			return;
		}
		OverrideRepository or = new OverrideRepository();
		preReverseTableByFilter(matchTables, or);
		configuration.readFromJDBC(getCatalogName(), getSchemaName());
		doExportPojo();
	}

	protected void preReverseTable(String[] tables, OverrideRepository or) {
		Table[] allTable = getAllTables();
		for (Table t : allTable) {
			for (String tableName : tables) {
				if (!tableName.equalsIgnoreCase(t.getName())) {
					TableFilter filter = new TableFilter();
					filter.setExclude(true);
					filter.setMatchName(t.getName());
					or.addTableFilter(filter);
				}
			}
		}
		or.packReverseEngineeringStrategy(configuration);
	}

	protected void preReverseTableByFilter(String[] matchTables, OverrideRepository or) {
		for (String matchTableName : matchTables) {
			TableFilter filter = new TableFilter();
			filter.setExclude(true);
			filter.setMatchName(matchTableName);
			or.addTableFilter(filter);
			or.packReverseEngineeringStrategy(configuration);
		}
	}

	private void doUpdateTables(List<JpaEntityCfg> jpaEntityCfgList) {
		if (jpaEntityCfgList == null || jpaEntityCfgList.size() < 1) {
			return;
		}
		// 向数据库写入操作，需要重新创建Configuration.
		JDBCMetaDataConfiguration cfg = createConfiguration();
		for (JpaEntityCfg jpaEntityCfg : jpaEntityCfgList) {
			cfg.addAnnotatedClass(jpaEntityCfg.getEntityClass());
		}
		new SchemaUpdate(cfg, cfg.buildSettings()).execute(script, true);
		
		// 更新实体类注释
		updateAllComment();
	}
	
	// hibernate反转出来的是标准SQL，而非特定平台的SQL。所以，放弃反转SQL。
	// public void exportDdl(String exportFile) {
	// configuration.readFromJDBC(getCatalogName(), getSchemaName());
	// doExportDdl(exportFile);
	// }
	//
	// public void exportDdlByTable(String exportFile, String[] tables) {
	// if (tables == null || tables.length < 1) {
	// return ;
	// }
	// OverrideRepository or = new OverrideRepository();
	// preReverseTable(tables, or);
	// configuration.readFromJDBC(getCatalogName(), getSchemaName());
	// doExportDdl(exportFile);
	// }
	//
	// public void exportDdlByFilter(String exportFile, String[] matchTables) {
	// if (matchTables == null || matchTables.length < 1) {
	// return ;
	// }
	// OverrideRepository or = new OverrideRepository();
	// preReverseTableByFilter(matchTables, or);
	// configuration.readFromJDBC(getCatalogName(), getSchemaName());
	// doExportDdl(exportFile);
	// }
}
